<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title>Low Power Listening</title>
<meta name="author" content="David Moss, Jonathan Hui, Kevin Klues" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2009/02/03 23:07:32 $
:version: $Revision: 1.2 $
:copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
*/
body {
  font-family: Times;
  font-size: 16px;
}

.first {
  margin-top: 0 ! important }

.last {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dd {
  margin-bottom: 0.5em }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning, div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title,
div.admonition p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 0em 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1 {
  font-family: Arial, sans-serif;
  font-size: 20px;
}

h1.title {
 text-align: center;
 font-size: 32px;
}

h2 {
 font-size: 16px;
 font-family: Arial, sans-serif;
}

h2.subtitle {
  text-align: center }

h3 {
 font-size: 12px;
 font-family: Arial, sans-serif;
}

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee;
  border-color: #000000;
  border-width: thin; 
  font-size: 14px
}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em;
}

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap;
  }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {}

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="low-power-listening">
<h1 class="title">Low Power Listening</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">TEP:</th><td class="field-body">105</td>
</tr>
<tr class="field"><th class="docinfo-name">Group:</th><td class="field-body">Core Working Group</td>
</tr>
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
<td>Final</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>David Moss, Jonathan Hui, Kevin Klues</td></tr>
</tbody>
</table>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">This memo documents a part of TinyOS for the TinyOS Community, and
requests discussion and suggestions for improvements.  Distribution
of this memo is unlimited. This memo is in full compliance with
TEP 1.</p>
</div>
<div class="section">
<h1><a id="abstract" name="abstract">Abstract</a></h1>
<p>This TEP describes the structure and implementation of the TinyOS 2.x
link layer abstractions. The architecture is designed to allow each radio
type to implement its own low power strategy within the Hardware Adaptation
Layer (HAL), while maintaining a common application interface.  The
history and strategies for low power listening are discussed, as well
as expected behavior and implementation recommendations.</p>
</div>
<div class="section">
<h1><a id="introduction" name="introduction">1. Introduction</a></h1>
<p>Asynchronous low power listening is a strategy used to duty cycle
the radio while ensuring reliable message delivery since TinyOS 1.x
<a class="citation-reference" href="#mica2" id="id1" name="id1">[MICA2]</a>.</p>
<p>While a CC1000 or CC2420 radio is turned on and listening, it can
actively consume anywhere between 7.4 to 18.8 mA on top of the power
consumed by other components in the system <a class="citation-reference" href="#cc1000" id="id2" name="id2">[CC1000]</a>,[CC2420]_.
This can rapidly deplete batteries.  In the interest of extending
battery lifetime, it is best to duty cycle the radio on and off to
prevent this idle waste of energy.  In an asychronous low power
message delivery scheme, the duty cycling receiver node saves the
most energy by performing short, periodic receive checks.  The power
consumption burden is then placed on the transmitter node, which
must modulate the radio channel long enough for the recipient?s
receive check to detect an incoming message.  A synchronous low
power message delivery scheme takes this idea a step further by
allowing the transmitter to only transmit when it knows the
destination node is performing a receive check.</p>
</div>
<div class="section">
<h1><a id="background" name="background">2. Background</a></h1>
<div class="section">
<h2><a id="early-tinyos-1-x-cc1000-low-power-listening-implementation" name="early-tinyos-1-x-cc1000-low-power-listening-implementation">2.1 Early TinyOS 1.x CC1000 Low Power Listening Implementation</a></h2>
<p>TinyOS 1.x introduced low power listening on the CC1000 radio, but
never introduced a similar scheme for the CC2420 radio in the baseline.
The CC1000 radio had the following low power listening commands,
provided directly by CC1000RadioIntM::</p>
<pre class="literal-block">
command result_t SetListeningMode(uint8_t power);
command uint8_t GetListeningMode();
command result_t SetTransmitMode(uint8_t power);
command uint8_t GetTransmitMode();
</pre>
<p>The uint8_t 'power' mode parameter was initially defined as follows::</p>
<pre class="literal-block">
//Original CC1000 Low Power Listening Modes
Power Mode 0 = 100% duty cycle
Power Mode 1 = 35.5% duty cycle
Power Mode 2 = 11.5% duty cycle
Power Mode 3 = 7.53% duty cycle
Power Mode 4 = 5.61% duty cycle
Power Mode 5 = 2.22% duty cycle
Power Mode 6 = 1.00% duty cycle
</pre>
<p>There were several issues with this interface and implementation.
First, setting up a low power network was cumbersome.  The low power
listening commands had to be directly wired through CC1000RadioIntM,
and called while the radio was not performing any transactions.
Second, each node in a network was expected to have the same radio
power mode.  Finally, the pre-programmed duty cycles were not linear
and offered a very limited selection of options.</p>
<p>In this low power listening implementation, the transmitter mote would
transmit a packet that consisted of an extremely long preamble.  This
preamble was long enough to span a complete receive check period.   On
the receiver?s end, the radio would turn on and read bits from the
radio.  If a preamble sequence was detected in the incoming bits, the
receiver?s radio would remain on for the full duration of the
transmitter?s preamble and wait for the packet at the end.</p>
<p>This original low power listening scheme was rather inefficient on both
the transmit and receive end.  On the receive end, turning on the radio
completely and reading in bits typically cost much more energy than
necessary.  The transmitter's long preamble could end up costing both
nodes to have their radios on much longer than required, sending and
receiving useless preamble bits.</p>
</div>
<div class="section">
<h2><a id="cc1000-pulse-check-implementation" name="cc1000-pulse-check-implementation">2.2 CC1000 Pulse Check Implementation</a></h2>
<p>Joe Polastre and Jason Hill developed a better receive check
implementation in the CC1000 ?Pulse Check? radio stack for TinyOS 1.x,
while maintaining the same interface.  This implementation took advantage
of a Clear Channel Assessment (CCA) to determine if a transmitter was
nearby.</p>
<p>In this implementation, the CC1000 radio did not have to be turned on
completely, so it consumed less maximum current than the previous
implementation.  The radio on-time was also significantly reduced, only
turning on long enough for a single ADC conversion to occur.  If energy
was detected on the channel after the first ADC conversion, subsequent
ADC conversions would verify this before committing to turning the
radio receiver on completely.</p>
<p>In this implementation the receiver's efficiency dramatically improved,
but the transmitter still sent a long, inefficient preamble.  Energy
consumption used to transmit messages was still high, while throughput
was still low.</p>
</div>
<div class="section">
<h2><a id="possible-improvements" name="possible-improvements">2.3 Possible Improvements</a></h2>
<p>Low power listening is a struggle between minimizing energy efficiency
and maximizing throughput.   In an asynchronous low power listening
scheme, several improvements can be made over earlier implementations.
One improvement that could have been made to earlier implementations is
to remove the long transmitted preamble and send many smaller messages
instead.  For example, the transmitter could send the same message over
and over again for the duration of the receiver's receive check period.
The receiver could wake up and see that another node is transmitting,
receive a full message, and finally send back an acknowledgement for that
message.  The transmitter would see the acknowledgement and stop
transmitting early, so both nodes can perform some high speed transaction
or go back to sleep.  Useless preamble bits are minimized while useful
packet information is maximized.  Incidentally, this is a good strategy
for CC2420 low power listening.  This strategy certainly improves energy
efficiency and throughput, but further improvements may be possible by
employing a synchronous delivery method on top of this type of
asynchronous low power listening scheme.</p>
<p>Improvements can also be made to the original low power listening
interfaces.  For example, instead of pre-programming power modes and
duty cycles, a low power listening interface should allow the developer
the flexibility to deploy a network of nodes with whatever duty cycle
percentage or sleep time desired for each individual node.  Nodes with
different receive check periods should still have the ability to
reliably communicate with each other with little difficulty.</p>
</div>
</div>
<div class="section">
<h1><a id="interfaces" name="interfaces">3. Interfaces</a></h1>
</div>
<div class="section">
<h1><a id="low-power-listening-interface" name="low-power-listening-interface">3.1 Low Power Listening Interface</a></h1>
<p>The LowPowerListening interface MUST be provided for each radio by the
platform independent ActiveMessageC configuration.</p>
<p>In some implementations, low power listening may have an option to
compile into the radio stack for memory footprint reasons.  If low
power listening is not compiled in with the stack, calls to
LowPowerListening MUST be handled by a dummy implementation.</p>
<p>The TEP proposes this LowPowerListening interface::</p>
<pre class="literal-block">
interface LowPowerListening {
  command void setLocalSleepInterval(uint16_t sleepIntervalMs);
  command uint16_t getLocalSleepInterval();
  command void setLocalDutyCycle(uint16_t dutyCycle);
  command uint16_t getLocalDutyCycle();
  command void setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs);
  command uint16_t getRxSleepInterval(message_t *msg);
  command void setRxDutyCycle(message_t *msg, uint16_t dutyCycle);
  command uint16_t getRxDutyCycle(message_t *msg);
  command uint16_t dutyCycleToSleepInterval(uint16_t dutyCycle);
  command uint16_t sleepIntervalToDutyCycle(uint16_t sleepInterval);
}
</pre>
<dl class="docutils">
<dt>setLocalSleepInterval(uint16_t sleepIntervalMs)</dt>
<dd><ul class="first last simple">
<li>Sets the local node?s radio sleep interval, in milliseconds.</li>
</ul>
</dd>
<dt>getLocalSleepInterval()</dt>
<dd><ul class="first last simple">
<li>Retrieves the local node?s sleep interval, in milliseconds.  If duty cycle percentage was originally set, it is automatically converted to a sleep interval.</li>
</ul>
</dd>
<dt>setLocalDutyCycle(uint16_t dutyCycle)</dt>
<dd><ul class="first last simple">
<li>Set the local node?s duty cycle percentage, in units of [percentage*100].</li>
</ul>
</dd>
<dt>getLocalDutyCycle()</dt>
<dd><ul class="first last simple">
<li>Retrieves the local node?s duty cycle percentage.  If sleep interval in milliseconds was originally set, it is automatically converted to a duty cycle percentage.</li>
</ul>
</dd>
<dt>setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs)</dt>
<dd><ul class="first last simple">
<li>The given message will soon be sent to a low power receiver. The sleepIntervalMs is the sleep interval of that low power receiver, in milliseconds.  When sent, the radio stack will automatically transmit the message so as to be detected by the low power receiver.</li>
</ul>
</dd>
<dt>getRxSleepInterval(message_t *msg)</dt>
<dd><ul class="first last simple">
<li>Retrieves the message destination?s sleep interval.  If a duty cycle was originally set for the outgoing message, it is automatically converted to a sleep interval.</li>
</ul>
</dd>
<dt>setRxDutyCycle(message_t *msg, uint16_t dutyCycle)</dt>
<dd><ul class="first last simple">
<li>The given message will soon be sent to a low power receiver.  The dutyCycle is the duty cycle percentage, in units of [percentage*100], of that low power receiver.  When sent, the radio stack will automatically transmit the message so as to be detected by the low power receiver.</li>
</ul>
</dd>
<dt>getRxDutyCycle(message_t *msg)</dt>
<dd><ul class="first last simple">
<li>Retrieves the message destination?s duty cycle percentage.  If a sleep interval was originally set for the outgoing message, it is automatically converted to a duty cycle percentage.</li>
</ul>
</dd>
<dt>dutyCycleToSleepInterval(uint16_t dutyCycle)</dt>
<dd><ul class="first last simple">
<li>Converts the given duty cycle percentage to a sleep interval in milliseconds.</li>
</ul>
</dd>
<dt>sleepIntervalToDutyCycle(uint16_t sleepInterval)</dt>
<dd><ul class="first last simple">
<li>Converts the given sleep interval in milliseconds to a duty cycle percentage.</li>
</ul>
</dd>
</dl>
<div class="section">
<h2><a id="split-control-behaviour" name="split-control-behaviour">3.2 Split Control Behaviour</a></h2>
<p>Low power listening MUST be enabled and disabled through the radio?s
standard SplitControl interface, returning exactly one SplitControl
event upon completion.  While the radio is duty cycling, it MUST NOT
alert the application layer each time the radio turns on and off to
perform a receive check or send a message.</p>
</div>
<div class="section">
<h2><a id="send-interface-behaviour" name="send-interface-behaviour">3.3 Send Interface Behaviour</a></h2>
<p>Attempts to send a message before SplitControl.start() has been called
SHOULD return EOFF, signifying the radio has not been enabled.  When
SplitControl.start() has been called by the application layer, calls
to Send MUST turn the radio on automatically if the radio is currently
off due to duty cycling.  If a message is already in the process of
being sent, multiple calls to Send should return FAIL.</p>
<p>The Send.sendDone(?) event SHOULD signal SUCCESS upon the successful
completion of the message delivery process, regardless if any mote
actually received the message.</p>
</div>
<div class="section">
<h2><a id="receive-interface-behaviour" name="receive-interface-behaviour">3.4 Receive Interface Behaviour</a></h2>
<p>Upon the successful reception of a message, the low power receive event
handler SHOULD drop duplicate messages sent to the broadcast address.
For example, the CC2420 implementation can perform this by checking
the message_t?s dsn value, where each dsn value is identical for every
message used in the delivery.</p>
<p>After the first successful message reception, the receiver?s radio
SHOULD stay on for a brief period of time to allow any further
transactions to occur at high speed.  If no subsequent messages are
detected going inbound or outbound after some short delay, the radio
MUST continue duty cycling as configured.</p>
</div>
</div>
<div class="section">
<h1><a id="low-power-listening-message-t-metadata" name="low-power-listening-message-t-metadata">4. Low Power Listening message_t Metadata</a></h1>
<p>To store the extra 16-bit receiver low power listening value, the radio
stack?s message_t footer MUST contain a parameter to store the message
destination?s receive check sleep interval in milliseconds or duty cycle
percentage.  For example, the low power listening CC2420 message_t footer
stores the message's receive check interval in milliseconds, as shown
below <a class="citation-reference" href="#tep111" id="id3" name="id3">[TEP111]</a>.:</p>
<pre class="literal-block">
typedef nx_struct cc2420_metadata_t {
  nx_uint8_t tx_power;
  nx_uint8_t rssi;
  nx_uint8_t lqi;
  nx_bool crc;
  nx_bool ack;
  nx_uint16_t time;
  nx_uint16_t rxInterval;
} cc2420_metadata_t;
</pre>
</div>
<div class="section">
<h1><a id="recommendations-for-hal-implementation" name="recommendations-for-hal-implementation">5. Recommendations for HAL Implementation</a></h1>
<p>In the interest of minimizing energy while maximizing throughput, it
is RECOMMENDED that any asynchronous low power listening implementation
use clear channel assessment methods to determine the presence of a
nearby transmitter.  It is also RECOMMENDED that the transmitter send
duplicate messages continuously with minimum or no backoff period instead
of one long message.  Removing backoffs on a continuous send delivery
scheme will allow the channel to be modulated sufficiently for a receiver
to quickly detect; furthermore, enabling acknowledgements on each
outgoing duplicate packet will allow the transmit period to be cut short
based on when the receiver actually receives the message.</p>
<p>Asynchronous low power listening requires some memory overhead, so
sometimes it is better to leave the added architecture out when it is
not required.  When it is feasible to do so, it is RECOMMENDED that
the preprocessor variable LOW_POWER_LISTENING be defined when low
power listening functionality is to be compiled in with the radio stack,
and not defined when low power listening functionality shouldn?t exist.</p>
<p>It is RECOMMENDED that the radio on-time for actual receive checks be a
measured value to help approximate the duty cycle percentage.</p>
</div>
<div class="section">
<h1><a id="author-s-address" name="author-s-address">6. Author's Address</a></h1>
<div class="line-block">
<div class="line">David Moss</div>
<div class="line">Rincon Research Corporation</div>
<div class="line">101 N. Wilmot, Suite 101</div>
<div class="line">Tucson, AZ  85750</div>
<div class="line"><br /></div>
<div class="line">phone - +1 520 519 3138</div>
<div class="line">email ? <a class="reference" href="mailto:dmm&#64;rincon.com">dmm&#64;rincon.com</a></div>
<div class="line"><br /></div>
<div class="line">Jonathan Hui</div>
<div class="line">657 Mission St. Ste. 600</div>
<div class="line">Arched Rock Corporation</div>
<div class="line">San Francisco, CA 94105-4120</div>
<div class="line"><br /></div>
<div class="line">phone - +1 415 692 0828</div>
<div class="line">email - <a class="reference" href="mailto:jhui&#64;archedrock.com">jhui&#64;archedrock.com</a></div>
<div class="line"><br /></div>
<div class="line">Kevin Klues</div>
<div class="line">503 Bryan Hall</div>
<div class="line">Washington University</div>
<div class="line">St. Louis, MO 63130</div>
<div class="line"><br /></div>
<div class="line">phone - +1-314-935-6355</div>
<div class="line">email - <a class="reference" href="mailto:klueska&#64;cs.wustl.edu">klueska&#64;cs.wustl.edu</a></div>
</div>
</div>
<div class="section">
<h1><a id="citations" name="citations">7. Citations</a></h1>
<table class="docutils citation" frame="void" id="mica2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="mica2">[MICA2]</a></td><td>&quot;MICA2 Radio Stack for TinyOS.&quot;  <a class="reference" href="http://www.tinyos.net/tinyos-1.x/doc/mica2radio/CC1000.html">http://www.tinyos.net/tinyos-1.x/doc/mica2radio/CC1000.html</a></td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep111" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3" name="tep111">[TEP111]</a></td><td>TEP 111: message_t.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="cc1000" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2" name="cc1000">[CC1000]</a></td><td>TI/Chipcon CC1000 Datasheet.  <a class="reference" href="http://www.chipcon.com/files/CC1000_Data_Sheet_2_2.pdf">http://www.chipcon.com/files/CC1000_Data_Sheet_2_2.pdf</a></td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="cc2420" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="cc2420">[CC2420]</a></td><td>TI/Chipcon CC2420 Datasheet.  <a class="reference" href="http://www.chipcon.com/files/CC2420_Data_Sheet_1_3.pdf">http://www.chipcon.com/files/CC2420_Data_Sheet_1_3.pdf</a></td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
